<?php

namespace App\HttpController\Api;

use App\Think\Org\Ems;
use App\Think\Org\Sms;
use App\Think\Random;
use App\Think\Validate;
use App\Think\Cache;
use App\Think\Db;
use App\Think\Config;

use App\Model\Notice as NoticeModel;
use App\Model\Bonus as BonusLib;
use App\Think\Captcha;

/**
 * 会员接口User
 */
class User extends ApiBase
{
    protected $noNeedLogin = ['login', 'mobilelogin', 'register', 'resetpwd', 'changeemail', 'changemobile', 'third'];

    /**
     * 会员中心
     */
    public function index()
    {
        $conf = Config::get('Project');
        $user_id = $this->auth->id;

        $info = Db::name('user')->field('id,paypass,group_id,invite_user_id,invite_code,username,nickname,email,mobile,avatar,level,birthday,money,money_freeze,logintime,loginip,jointime, status')->where("id='{$user_id}'")->cache("userIndex:{$user_id}",60)->find();
        $info['agent_status'] = (int)Db::name('agent')->where("user_id='{$user_id}'")->value('status');
        //上级邀请码
        $info['parent_invite_code'] = (string)Db::name('user')->field('invite_code')->where("id='{$info['invite_user_id']}'")->cache(3600)->value('invite_code');
        //头像详细路径
        $info['avatar'] = $conf['cdn_url'].$info['avatar'];
        //统计信息
        $stat_info = Db::name('stats_user')->field('total_recharge,total_valid')->where("user_id='{$user_id}'")->cache("userIndexStat:{$user_id}", 60)->find();
        $stat_info = ['total_recharge'=>(string)$stat_info['total_recharge'], 'total_valid'=>(string)$stat_info['total_valid']];
		//等级信息
        $levels = Db::name('user_level')->field('*')->cache(3600)->select();
        $level_info = arr_row($levels, 'id', $info['level']);
        $level_next = arr_row($levels, 'id', $info['level']+1);
        $level_up = [
            // 'current' => arr_field($levels, 'id', $info['level'], 'need_money_valid'),
            'name_cur'        => $level_info['name'],
            'need_relegation' => $level_info['relegation_money_valid'],
            'day_cashout_time'  => $level_info['day_cashout_time'],
            'day_cashout_money' => $level_info['day_cashout_money'],

            'name_next'       => $level_next['name'],
            'need_recharge'   => $level_next['need_recharge'],
            'need_valid'      => $level_next['need_money_valid'],
        ];

        //触发会员升级红利
        if($level_up['need_recharge']<=$stat_info['total_recharge'] && $level_up['need_valid']<=$stat_info['total_valid']){
            BonusLib::upgrade($user_id);
            cache("userIndexStat:{$user_id}",NULL);
        }
        //触发生日红利
        if(substr($info['birthday'], 5) == date('m-d')){ // 生日当天
            $year = date('Y');
            if(!db_get_field('trade_bonus', "user_id='{$user_id}' AND bonus_type='birth' AND ext_json->'$.year'='{$year}' ", 'id')) { //未领取过今年的红利
                // $tmpUser = Db::name('user u')->field('u.birthday,u.jointime,ul.*')->join('user_level ul', 'u.level=ul.id', 'LEFT')->where("u.id='{$user_id}'")->find();
                if($level_info['ac_birth']>0) { //用户等级生日礼金>0
                    if( (time()-$info['jointime'])>86400*90 ) //加入平台必须满3个月  
                        BonusLib::birth($user_id);
                }
            }
        }

        return $this->success('success', ['info'=>$info, 'stat'=>$stat_info, 'level_up'=>$level_up, 'level_info'=>$level_info]);
    }

    /**
     * 会员登录
     * ApiMethod (POST)
     * @param string $account  账号
     * @param string $password 密码
     */
    public function login()
    {
        $account = $this->input('account');
        $password = $this->input('password');
        if (!$account || !$password) return $this->error(__('请求参数不完整'));
        
        //登录太频繁限制
        if(!$this->requestLimit("loginTime:{$account}", 6, 120, '登录太频繁,请稍后操作')) return false;

        $ret = $this->auth->login($account, $password);
        if ($ret) {
            $data = ['userinfo' => $this->auth->getUserinfo()];
            // $count = Db::name('user_token')->where("user_id='{$data['userinfo']['id']}' AND createtime>='".strtotime('-5 minute')."'")->count();
            // if($count >= 8) return $this->error(__('登录太频繁,请稍后操作'));
            return $this->success(__('Logged in successful'), $data);
        } else {
            return $this->error($this->auth->getError());
        }
    }

    /**
     * 手机验证码登录
     * ApiMethod (POST)
     * @param string $mobile  手机号
     * @param string $captcha 短信验证码
     * @param string $invite_code 邀请码|可选
     */
    public function mobilelogin()
    {
        $mobile = $this->input('mobile');
        $captcha = $this->input('captcha');
        $invite_code = $this->input('invite_code');

        if (!$mobile || !$captcha) {
            return $this->error(__('请求参数不完整'));
        }
        if (!Validate::regex($mobile, "^1\d{10}$")) {
            return $this->error(__('手机号格式不正确'));
        }
        if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
            return $this->error(__('验证码不正确'));
        }
        $user = db_get_row('user', "mobile='{$mobile}'");
        if ($user) {
            if ($user->status != 'normal') return $this->error(__('Account is locked'));
            //如果已经有账号则直接登录
            $ret = $this->auth->direct($user->id);
        } else {
            //邀请注册
            $extend['invite_user_id'] = (int)Db::name('user')->where("invite_code='{$invite_code}'")->value('id');
            $extend['invite_code'] = rand_str(6,'lowerchar');
            $extend['group_id'] = 1;
            $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, $extend);
        }
        if ($ret) {
            Sms::flush($mobile, 'mobilelogin');
            $data = ['userinfo' => $this->auth->getUserinfo()];
            return $this->success(__('Logged in successful'), $data);
        } else {
            return $this->error($this->auth->getError());
        }
    }

    /**
     * 注册会员
     * ApiMethod (POST)
     * @param string $username 用户名
     * @param string $password 密码
     * @param string $captcha  图形验证码
     * @param string $captcha_id  图形验证码ID
     * @param string $email    邮箱|可选
     * @param string $mobile   手机号|可选
     * @param string $code     短信验证码|可选
     * @param string $invite_code 邀请码|可选
     * @param string $from 来源标识|可选
     */
    public function register()
    {
        $username    = $this->input('username');
        $password    = $this->input('password');
        $captcha     = $this->input('captcha');
        $captcha_id  = $this->input('captcha_id');

        $email       = $this->input('email');
        $mobile      = $this->input('mobile');
        $code        = $this->input('code');
        $invite_code = (string)$this->input('invite_code');
        $from        = (string)$this->input('from');

        if (!$username || !$password || !$captcha || !$captcha_id) {
            return $this->error(__('请求参数不完整'));
        }
        if(mb_strlen($username,"utf-8")<5 || mb_strlen($username,"utf-8")>25) return $this->error(__('用户名长度需在5-25个字符以内'));
        // if ($email && !Validate::is($email, "email")) {
        //     return $this->error(__('Email is incorrect'));
        // }
        // if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
        //     return $this->error(__('手机号格式不正确'));
        // }
        // $ret = Sms::check($mobile, $code, 'register');
        // if (!$ret) {
        //     return $this->error(__('验证码不正确'));
        // }
        $cls = new Captcha();
        if(!$cls->captcha_check($captcha, $captcha_id)) return $this->error(__('验证码不正确'));
        
        $extend['invite_user_id'] = 0;
        $extend['group_id'] = 1;
        $extend['invite_code'] = rand_str(6,'lowerchar');
        //邀请注册:1/邀请域名,2/邀请码
        $from = ltrim($from,'www.');
        if(!empty($from)){ //域名推荐
            $extend['invite_user_id'] = (int)Db::name('agent')->where("domain='{$from}'")->value('user_id');
        }
        if($extend['invite_user_id'] == 0 && !empty($invite_code)){ //无域名推荐，有邀请码
            $extend['invite_user_id'] = (int)Db::name('user')->where("invite_code='{$invite_code}'")->value('id');
            if($extend['invite_user_id']<=0) return $this->error(__('邀请码不正确'));
        }
        //无域名推荐，无邀请码
        if($extend['invite_user_id'] == 0 || empty($extend['invite_user_id'])) $extend['invite_user_id'] = 1;
        
        $ret = $this->auth->register($username, $password, $email, $mobile, $extend);
        if ($ret) {
            //注册成功
            $data = ['userinfo' => $this->auth->getUserinfo()];
            $user_id = (int)$data['userinfo']['id'];

            //增加用户统计            
            Db::name('stats_user')->strict(false)->insert([ 'user_id'=>$user_id, 'createtime'=>time(), 'updatetime'=>time() ]);

            //发送红利给邀请人
            // if($extend['invite_user_id'] > 1 && ($extend['invite_user_id'] != $user_id) && $data['userinfo']['is_agent'] == 0){
            //     BonusLib::invite($extend['invite_user_id'], $user_id); //邀请送红利
            // } 
            
            //发送通知|reg_user=直接注册，reg_user_invite=通过邀请码注册
            if(empty($invite_code)) NoticeModel::reg_user(['user_id'=>$user_id]);
            if(!empty($invite_code)) NoticeModel::reg_user_invite(['user_id'=>$user_id]);

            return $this->success(__('Sign up successful'), $data);
        } else {
            return $this->error($this->auth->getError());
        }
    }

    /**
     * 注销登录
     * ApiMethod (POST)
     */
    public function logout()
    {
        $this->auth->logout();
        return $this->success(__('Logout successful'));
    }

    /**
     * 修改个人信息
     * ApiMethod (POST)
     * @param string $avatar   头像地址
     * @param string $nickname 真实姓名
     * @param string $birthday 生日
     * @param string $bio      个人简介
     * @param string $gender   性别
     * @param string $address  收货地址|格式：省|市|区|详细地址
     * 
     * @param string $paypass  支付密码
     * @param string $oldpaypass  旧支付密码
     * 
     */
    public function profile()
    {
        $user = $this->auth->getUser();
        $username = $this->input('username');
        $nickname = $this->input('nickname');
        $birthday = $this->input('birthday');
        $bio = $this->input('bio');
        $gender = $this->input('gender');
        $address = $this->input('address');

        $paypass = $this->input('paypass');
        $oldpaypass = $this->input('oldpaypass');
        $avatar = $this->input('avatar', '', 'trim,strip_tags,htmlspecialchars');
        if ($username) {
            $exists = Db::name('user')->where("username='{$username}' AND id <> {$this->auth->id}")->find();
            if ($exists) {
                return $this->error(__('Username already exists'));
            }
            // $user->username = $username;
        }
        if ($paypass) {
            //已经设置
            $db_paypass = Db::name('user')->where("id='{$this->auth->id}'")->value('paypass');
            if(!empty($db_paypass) && $this->auth->getEncryptPassword($oldpaypass) != $this->auth->paypass) return $this->error(__('旧的支付密码不正确'));
            $user->paypass = $this->auth->getEncryptPassword($paypass);
        }
        if($nickname) $user->nickname = $nickname;
        if($birthday) $user->birthday = $birthday;
        if($bio) $user->bio = $bio;
        if($avatar) $user->avatar = str_replace(Config::get('Project.cdn_url'), '', $avatar);
        if($gender) $user->gender = $gender;
        if($address) $user->address = $address;
        $user->save();
        cache("userIndex:{$this->auth->id}",NULL);
        return $this->success('', $this->auth->getUserInfo() );
    }

    /**
     * 修改邮箱
     * ApiMethod (POST)
     * @param string $email   邮箱
     * @param string $captcha 验证码
     */
    public function changeemail()
    {
        $user = $this->auth->getUser();
        $email = $this->request->post('email');
        $captcha = $this->input('captcha');
        if (!$email || !$captcha) {
            return $this->error(__('请求参数不完整'));
        }
        if (!Validate::is($email, "email")) {
            return $this->error(__('Email is incorrect'));
        }
        if (Db::name('user')->where("email='{$email}' AND id <> {$user->id}")->find()) {
            return $this->error(__('该邮箱已被他人绑定'));
        }
        $result = Ems::check($email, $captcha, 'changeemail');
        if (!$result) {
            return $this->error(__('验证码不正确'));
        }
        $verification = $user->verification;
        $verification->email = 1;
        $user->verification = $verification;
        $user->email = $email;
        $user->save();

        Ems::flush($email, 'changeemail');
        return $this->success();
    }

    /**
     * 修改手机号
     * ApiMethod (POST)
     * @param string $mobile   手机号
     * @param string $captcha 验证码
     */
    public function changemobile()
    {
        $user = $this->auth->getUser();
        $mobile = $this->input('mobile');
        $captcha = $this->input('captcha');
        if (!$mobile || !$captcha) {
            return $this->error(__('请求参数不完整'));
        }
        if (!Validate::regex($mobile, "^1\d{10}$")) {
            return $this->error(__('手机号格式不正确'));
        }
        if (Db::name('user')->where("mobile='{$mobile}' AND id <> {$user->id}")->find()) {
            return $this->error(__('Mobile already exists'));
        }
        $result = Sms::check($mobile, $captcha, 'changemobile');
        if (!$result) {
            return $this->error(__('验证码不正确'));
        }
        $verification = $user->verification;
        $verification->mobile = 1;
        $user->verification = $verification;
        $user->mobile = $mobile;
        $user->save();

        //发放注册红利
        if(!db_get_field('trade_bonus', "user_id='{$user->id}' AND bonus_type='register'", 'id')) BonusLib::register($user->id); 

        Sms::flush($mobile, 'changemobile');
        return $this->success();
    }

    /**
     * 第三方登录
     * ApiMethod (POST)
     * @param string $platform 平台名称
     * @param string $code     Code码
     */
    public function third()
    {
        $url = url('user/index');
        $platform = $this->input("platform");
        $code = $this->input("code");
        $config = get_addon_config('third');
        if (!$config || !isset($config[$platform])) {
            return $this->error(__('请求参数不完整'));
        }
        $app = new \addons\third\library\Application($config);
        //通过code换access_token和绑定会员
        $result = $app->{$platform}->getUserInfo(['code' => $code]);
        if ($result) {
            $loginret = \addons\third\library\Service::connect($platform, $result);
            if ($loginret) {
                $data = [
                    'userinfo'  => $this->auth->getUserinfo(),
                    'thirdinfo' => $result
                ];
                return $this->success(__('Logged in successful'), $data);
            }
        }
        return $this->error(__('Operation failed'), $url);
    }

    /**
     * 重置/修改密码
     * ApiMethod (POST)
     * @param string $type        找回方式|mobile=手机,email=邮箱,password=密码修改
     * @param string $newpassword 新密码
     * @param string $mobile      手机号|type=mobile时必选
     * @param string $email       邮件|type=email时必选
     * @param string $oldpassword 旧密码|type=password时必选
     * @param string $captcha     验证码|type=mobile或email时必选
     */
    public function resetpwd()
    {
        $type = $this->input("type");
        $mobile = $this->input("mobile");
        $email = $this->input("email");
        $oldpassword = $this->input("oldpassword");
        $newpassword = $this->input("newpassword");
        $captcha = $this->input("captcha");
        if (!$newpassword) return $this->error(__('请求参数不完整'));
        if ($type == 'mobile') {
            if (!$captcha) return $this->error(__('请求参数不完整'));
            if (!Validate::regex($mobile, "^1\d{10}$")) {
                return $this->error(__('手机号格式不正确'));
            }
            $user = db_get_row('user', "mobile='{$mobile}'");
            if (!$user) {
                return $this->error(__('请先绑定手机号'));
            }
            $ret = Sms::check($mobile, $captcha, 'resetpwd');
            if (!$ret) {
                return $this->error(__('验证码不正确'));
            }
            Sms::flush($mobile, 'resetpwd');
        } elseif($type == 'email') {
            if (!$captcha) return $this->error(__('请求参数不完整'));
            if (!Validate::is($email, "email")) {
                return $this->error(__('Email is incorrect'));
            }
            $user = db_get_row('user', "email='{$email}'");
            if (!$user) {
                return $this->error(__('请先绑定邮箱账号'));
            }
            $ret = Ems::check($email, $captcha, 'resetpwd');
            if (!$ret) {
                return $this->error(__('验证码不正确'));
            }
            Ems::flush($email, 'resetpwd');
        } else{
            if (!$oldpassword) return $this->error(__('请求参数不完整'));
            $user = $this->auth->getUser();
            if($user->password != $this->auth->getEncryptPassword($oldpassword, $user->salt)) return $this->error(__('Password is incorrect'));
        }
        //模拟一次登录
        $this->auth->direct($user->id);
        $ret = $this->auth->changepwd($newpassword, '', true);
        if ($ret) {
            return $this->success(__('Reset password successful'));
        } else {
            return $this->error($this->auth->getError());
        }
    }

    /**
     * 判断支付密码正确
     * ApiMethod (POST)
     * @param string $paypass   支付密码
     */
    public function check_paypass(){
        $paypass = $this->input('paypass');
        //已经设置
        $db_paypass = Db::name('user')->where("id='{$this->auth->id}'")->value('paypass');
        if(!empty($db_paypass) && $this->auth->getEncryptPassword($paypass) != $this->auth->paypass) return $this->error(__('支付密码不正确'));
        return $this->success();
    }

    /**
     * 银行卡列表
     * ApiMethod (POST)
     */
    public function bind_list(){
        $data = Db::name('user_bank')->where("user_id='{$this->auth->id}'")->select();
        return $this->success(__('success'), ['list'=>$data]);
    }
    /**
     * 绑定银行卡
     * ApiMethod (POST)
     * @param string $account   帐户名
     * @param string $bank_name 开户行
     * @param string $bank_no   银行卡号
     * @param string $opening   开户行
     * @param string $opening_area   开户地址
     * 
     * @param string $mobile    手机号
     * @param string $captcha   手机验证码
     */
    public function bank_bind(){
        $account   = $this->input("account");
        $bank_name = $this->input("bank_name");
        $bank_no   = $this->input("bank_no");
        $opening   = $this->input("opening");
        $opening_area = $this->input("opening_area");

        $mobile    = $this->input("mobile");
        $captcha   = $this->input("captcha");
        if(!$account || !$bank_name || !$bank_no || !$opening || !$opening_area) return $this->error(__('请求参数不完整'));
        if(!bankno_check($bank_no)) return $this->error(__('银行卡号不正确'));
        if(Db::name('user_bank')->where("bank_no='{$bank_no}'")->find()) return $this->error(__('该银行卡已经绑定'));

        $ret = Sms::check($mobile, $captcha, 'bank_bind');
        if (!$ret) return $this->error(__('验证码不正确'));

        $param = $this->request->param();
        $param['user_id'] = $this->auth->id;
        $param['createtime'] = time();
        if(!Db::name('user_bank')->strict(false)->insert($param)) return $this->error(__('绑定失败'));
        return $this->success(__('银行卡绑定成功'));
    }
    /**
     * 解绑银行卡
     * ApiMethod (POST)
     * @param string $bank_id   绑定ID
     */
    public function bank_unbind(){
        $bank_id = $this->input("bank_id");
        $user_id = $this->auth->id;
        if(!$bank_id) return $this->error(__('请求参数不完整'));
        $count = Db::name('user_bank')->where("user_id='{$user_id}'")->count();
        if($count <= 1) return $this->error(__('只有一张银行卡,无法解绑'));
        if(!Db::name('user_bank')->where("user_id='{$user_id}' AND id='{$bank_id}'")->delete()) return $this->error(__('解绑失败'));
        return $this->success(__('银行卡解绑成功'));
    }

}
